package cn.snowsoft.iot.module.warning.event;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.snowsoft.iot.framework.common.exception.ErrorCode;
import cn.snowsoft.iot.module.message.api.send.SendApi;
import cn.snowsoft.iot.module.message.api.send.dto.SendMessageRequestDto;
import cn.snowsoft.iot.module.system.api.dict.dto.DictDataRespDTO;
import cn.snowsoft.iot.module.warning.controller.admin.warning.config.vo.WarningCommonVO;
import cn.snowsoft.iot.module.warning.controller.admin.warning.config.vo.WarningDetailVO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.action.HTTPDO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.action.MQTTDO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.config.ConfigActionDO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.record.OutPutRecord;
import cn.snowsoft.iot.module.warning.mqtt.MqttClientUtil;
import cn.snowsoft.iot.module.warning.service.warning.record.IOutPutRecordService;
import cn.snowsoft.iot.module.warning.service.warning.record.IWarningRecordService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;

import static cn.snowsoft.iot.framework.common.exception.util.ServiceExceptionUtil.exception;


@Component
@RequiredArgsConstructor
@Slf4j
public class WarningEventHandler {

    private final IWarningRecordService warningRecordService;
    private final SendApi sendApi;

    private final RedisCacheManager redisCacheManager;


    @Async("eventAsyncExecutor")
    @EventListener({MysqlWarningEvent.class})
    public void handleMysqlAction(MysqlWarningEvent event) {
        JSONObject data = event.getJsonObject();
        data.put("uuId", event.getUuId());
        warningRecordService.handleWarningRecord(data, event.getWarningType());
        log.info("mysql持久化动作处理成功，请求内容 {}", event);
    }

    @Async("eventAsyncExecutor")
    @EventListener({MessageWarningEvent.class})
    public void handleMessageAction(MessageWarningEvent event) {
        String params = event.getParams();
        JSONObject data = JSONObject.parseObject(params);
        Long templateId = data.getLong("templateId");
        Map<String, Object> innerMap = data.getInnerMap();
        String uuId = event.getUuId();
        Long actionId = event.getActionId();
        Map<String, Object>  finalInnerMap = formatParam(innerMap,event);
        JSONArray userArray = data.getJSONArray("users");
        if (ObjectUtil.isEmpty(userArray)){
            throw exception(new ErrorCode(500,"发送用户不存在"));
        }
        userArray.forEach(user -> {
            List<String> users = new ArrayList();
            users.add(user.toString());
            SendMessageRequestDto requestBody = new SendMessageRequestDto(
                    templateId,
                    users,
                    finalInnerMap,
                    uuId,
                    actionId,
                    0);
            sendApi.sendMessage(requestBody);
            log.info("消息发送动作处理成功，请求内容 uuID:{} actionId:{} user:{} templateId:{}", uuId, actionId, user, templateId);
        });
    }



    public Map<String, Object> formatParam(Map<String, Object> paramMap,MessageWarningEvent event){

        HashMap<String,String> platFormMap = new HashMap();
        List<DictDataRespDTO> list = redisCacheManager.getCache("dictCache").get("message_params", List.class);

        for (DictDataRespDTO dictDataDO : list) {
            if ("platformName".equals(dictDataDO.getValue())){
                platFormMap.put("platformName", dictDataDO.getRemark());
            }
            if ("platformUrl".equals(dictDataDO.getValue())){
                platFormMap.put("platformUrl", dictDataDO.getRemark());
            }
            if ("dateTime".equals(dictDataDO.getValue())){
                platFormMap.put("dateTime", dictDataDO.getRemark());
            }
            if ("deviceName".equals(dictDataDO.getValue())){
                platFormMap.put("deviceName", dictDataDO.getRemark());
            }
            if ("deviceCode".equals(dictDataDO.getValue())){
                platFormMap.put("deviceCode", dictDataDO.getRemark());
            }
            if ("pointName".equals(dictDataDO.getValue())){
                platFormMap.put("pointName", dictDataDO.getRemark());
            }
            if ("pointCode".equals(dictDataDO.getValue())){
                platFormMap.put("pointCode", dictDataDO.getRemark());
            }
            if ("pointValue".equals(dictDataDO.getValue())){
                platFormMap.put("pointValue", dictDataDO.getRemark());
            }
        }
        JSONObject templateParam = (JSONObject) paramMap.get("templateParam");
        Map<String, Object> templateParamMap = templateParam.getInnerMap();

        templateParamMap.entrySet().forEach(entry -> {
            JSONObject jsonObject = event.getJsonObject();
            if ("dateTime".equals(entry.getValue())){
                templateParamMap.put(entry.getKey(),ObjectUtil.isEmpty(jsonObject)?"":jsonObject.get("thetime"));
            } else if ("deviceName".equals(entry.getValue())){
                templateParamMap.put(entry.getKey(),ObjectUtil.isEmpty(jsonObject)?"":jsonObject.get("deviceName"));
            } else if  ("deviceCode".equals(entry.getValue())){
                templateParamMap.put(entry.getKey(),ObjectUtil.isEmpty(jsonObject)?"":jsonObject.get("deviceCode"));
            }else {
                String s = platFormMap.get(entry.getValue().toString());
                templateParamMap.put(entry.getKey(), s);
            }
        });
        String s = JSONObject.toJSONString(templateParamMap);
        paramMap.put("templateParam",s);
        return paramMap;
    }

}
